BitMasking Example
by Brad D. Byrne

'Hey All, here's something you all might like:

'In another thread a member needed to speed up a IF/THEN
'procedure... ie. " IF doo(i)= daa(i) THEN dee(i)=1 "
'because the data of interest had a range (0-99)...
'this proc using: " deeDat(i) = dooDat(i) XOR daaDat(i) "
'can perform same task almost 5 times faster...
'don't know what it's called...
'so I called it "bitmasking???
'Hope you like,
'Brad

#COMPILE EXE
#INCLUDE "WIN32API.INC"

FUNCTION PBMAIN() AS LONG

DIM t1 AS QUAD ,t2 AS QUAD ,t3 AS QUAD ,t4 AS QUAD
DIM count AS LONG
DIM doo(119) AS LONG , daa(119) AS LONG , dee(119) AS LONG
DIM i&, j& ,k&

DIM dooDat(29) AS LONG
DIM daaDat(29) AS LONG
DIM deeDat(29) AS LONG

'add some data, here used "3" as ceiling 
'so to get matches but could be anything
RANDOMIZE TIMER
FOR i = 0 TO 119
doo(i) = RND(0,3)
daa(i) = RND(0,3)
NEXT i

'compress it - in this case we only are 
'interested in values 0-99 so a byte is sufficient
DIM ArrRecNum&, CmprssdIndex&

FOR ArrRecNum = 0 TO 119
   FOR CmprssdIndex = 0 TO 29
      i = doo(ArrRecNum)
      SHIFT LEFT i, 8
      i = i + doo(ArrRecNum+1)
      SHIFT LEFT i, 8
      i = i + doo(ArrRecNum+2)
      SHIFT LEFT i, 8
      i = i + doo(ArrRecNum+3)
      dooDat(CmprssdIndex) = i
      ArrRecNum = ArrRecNum +4
   NEXT
NEXT
FOR ArrRecNum = 0 TO 119
   FOR CmprssdIndex = 0 TO 29
      i = daa(ArrRecNum)
      SHIFT LEFT i, 8
      i = i + daa(ArrRecNum+1)
      SHIFT LEFT i, 8
      i = i + daa(ArrRecNum+2)
      SHIFT LEFT i, 8
      i = i + daa(ArrRecNum+3)
      daaDat(CmprssdIndex) = i
      ArrRecNum = ArrRecNum +4
   NEXT
NEXT

'make strings just to display that data is correct
DIM dooStr$, daaStr$ ,dooDatStr$ ,daaDatStr$

FOR i = 0 TO 30
   dooStr$ = dooStr$ + STR$(doo(i))+","
NEXT

FOR i = 0 TO 30
   daaStr$ = daaStr$ + STR$(daa(i))+","
NEXT

FOR i = 0 TO 30\4
   j = dooDat(i) : SHIFT RIGHT j, 24
   dooDatStr$ = dooDatStr$ + STR$(j AND &hFF)+","
   j = dooDat(i) : SHIFT RIGHT j, 16
   dooDatStr$ = dooDatStr$ + STR$(j AND &hFF)+","
   j = dooDat(i) : SHIFT RIGHT j, 8
   dooDatStr$ = dooDatStr$ + STR$(j AND &hFF)+","
   j = dooDat(i)
   dooDatStr$ = dooDatStr$ + STR$(j AND &hFF)+","
NEXT

FOR i = 0 TO 30\4
   j = daaDat(i) : SHIFT RIGHT j, 24
   daaDatStr$ = daaDatStr$ + STR$(j AND &hFF)+","
   j = daaDat(i) : SHIFT RIGHT j, 16
   daaDatStr$ = daaDatStr$ + STR$(j AND &hFF)+","
   j = daaDat(i) : SHIFT RIGHT j, 8
   daaDatStr$ = daaDatStr$ + STR$(j AND &hFF)+","
   j = daaDat(i)
   daaDatStr$ = daaDatStr$ + STR$(j AND &hFF)+","
NEXT

'display strings
MSGBOX "Display first 30 rec's to show data correct" + _
$CRLF + $CRLF + _
"dooStr$ :" + $CRLF + dooStr$ + $CRLF + _
"dooDatStr$ :" + $CRLF + dooDatStr$ + $CRLF + _
"daaStr$ :" + $CRLF + daaStr$ + $CRLF + _
"daaDatStr$ :" + $CRLF + daaDatStr$
MSGBOX "start"

'run IF/THEN Proc
QueryPerformanceCounter t1
FOR count = 1 TO 50000
   FOR i = 0 TO 120
      IF doo(i)= daa(i) THEN dee(i)=1
   NEXT i
NEXT count

QueryPerformanceCounter t2

'make deeStr$ just to display that data is correct
FOR i = 0 TO 30
   deeStr$ = deeStr$ + STR$(dee(i))+","
NEXT

MSGBOX "IF/THEN Proc: "+ $CRLF + $CRLF +_
"dooStr$ :" + $CRLF + dooStr$ + $CRLF + _
"daaStr$ :" + $CRLF + daaStr$ + $CRLF + _
"deeStr$ :" + $CRLF + deeStr$ + $CRLF + $CRLF +_
"IF/THEN time : " + (FORMAT$(t2-t1,"#0.00000"))

'run BITMASK XOR Proc
QueryPerformanceCounter t3
FOR count = 1 TO 50000
   FOR i = 0 TO 29
      deeDat(i) = dooDat(i) XOR daaDat(i)
   NEXT i
NEXT count
 
QueryPerformanceCounter t4

'make deeStr$ just to display that data is correct
FOR i = 0 TO 30\4
   j = deeDat(i) : SHIFT RIGHT j, 24
   deeDatStr$ = deeDatStr$ + STR$(j AND &hFF)+","
   j = deeDat(i) : SHIFT RIGHT j, 16
   deeDatStr$ = deeDatStr$ + STR$(j AND &hFF)+","
   j = deeDat(i) : SHIFT RIGHT j, 8
   deeDatStr$ = deeDatStr$ + STR$(j AND &hFF)+","
   j = deeDat(i)
   deeDatStr$ = deeDatStr$ + STR$(j AND &hFF)+","
NEXT

MSGBOX "BITMASK XOR Method: _
( if deeDat() is 0 then match )"+ $CRLF + $CRLF +_
"dooDatStr$ :" + $CRLF + dooDatStr$ + $CRLF + _
"daaDatStr$ :" + $CRLF + daaDatStr$ + $CRLF + _
"deeDatStr$ :" + $CRLF + deeDatStr$ + $CRLF + $CRLF +_
"BITMASK XOR time : " + (FORMAT$(t4-t3,"#0.00000")) + $CRLF +_
"IF/THEN time : " + (FORMAT$(t2-t1,"#0.00000"))

END FUNCTION




